package com.lhf.aicloud.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lhf.aicloud.entity.Discuss;
import com.lhf.aicloud.entity.DiscussSupport;
import com.lhf.aicloud.entity.User;
import com.lhf.aicloud.entity.dto.DiscussDTO;
import com.lhf.aicloud.entity.vo.CommentVO;
import com.lhf.aicloud.entity.vo.DiscussVO;
import com.lhf.aicloud.service.ICommentService;
import com.lhf.aicloud.service.IDiscussService;
import com.lhf.aicloud.service.IDiscussSupportService;
import com.lhf.aicloud.service.IUserService;
import com.lhf.aicloud.utils.AppVariable;
import com.lhf.aicloud.utils.ResponseEntity;
import com.lhf.aicloud.utils.SecurityUtils;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.kafka.support.Acknowledgment;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @author: lhf
 * @date: Created in 2024/08/12
 * @description:
 */
@Slf4j
@RestController
@RequestMapping("/discuss")
public class DiscussController {
    @Resource
    private IDiscussService discussService;

    @Resource
    private IUserService userService;

    @Resource
    private ICommentService commentService;

    @Resource
    private ThreadPoolTaskExecutor threadPool;

    @Resource
    private KafkaTemplate kafkaTemplate;

    @Resource
    private IDiscussSupportService discussSupportService;


    /**
     * 添加话题
     */
    @RequestMapping("/add")
    public ResponseEntity add(@Validated DiscussDTO discussDTO) {
        Discuss discuss = new Discuss();
        discuss.setTitle(discussDTO.getTitle());
        discuss.setContent(discussDTO.getContent());
        discuss.setUid(SecurityUtils.getCurrentUser().getUid());
        boolean result = discussService.save(discuss);
        if (result) {
            return ResponseEntity.success(result);
        }
        return ResponseEntity.error("添加失败");
    }

    /**
     * 获取话题列表
     *
     * @param pageNum 页码
     * @param type    1：推荐（点赞数排序）；2：最新（创建时间排序）
     */
    @RequestMapping("/list")
    public ResponseEntity list(Integer pageNum, Integer type) {
        if (pageNum == null || pageNum <= 0) {
            pageNum = 1;
        }
        if (type == null || type <= 0) {
            type = 1;
        }

        IPage<Discuss> page = new Page<>(pageNum, AppVariable.PAGE_SIZE);

        page = discussService.page(page, Wrappers.lambdaQuery(Discuss.class)
                .orderByDesc(type == 1, Discuss::getSupportcount)
                .orderByDesc(type == 2, Discuss::getCreatetime)
        );

        return ResponseEntity.success(page);
    }

    /**
     * 获取我的话题列表
     */
    @RequestMapping("/mylist")
    public ResponseEntity myList() {
        Long uid = SecurityUtils.getCurrentUser().getUid();
        LambdaQueryWrapper<Discuss> discussLambdaQueryWrapper = new LambdaQueryWrapper<Discuss>().eq(Discuss::getUid, uid)
                .orderByDesc(Discuss::getCreatetime);
        List<Discuss> list = discussService.list(discussLambdaQueryWrapper);
        return ResponseEntity.success(list);
    }

    /**
     * 删除话题
     */
    @RequestMapping("/delete")
    public ResponseEntity delete(Long did) {
        if (did == null || did <= 0) {
            return ResponseEntity.error("参数错误");
        }
        boolean result = discussService.remove(
                Wrappers.lambdaQuery(Discuss.class)
                        .eq(Discuss::getDid, did)
                        .eq(Discuss::getUid, SecurityUtils.getCurrentUser().getUid())
        );
        if (result) {
            return ResponseEntity.success("删除成功");
        }
        return ResponseEntity.error("删除失败");
    }

    /**
     * 查询讨论详情
     */
    @RequestMapping("/detail")
    public ResponseEntity detail(Long did) throws ExecutionException, InterruptedException {
        if (did == null || did <= 0) {
            return ResponseEntity.error("参数错误");
        }
        Discuss discuss = discussService.getById(did);
        if (discuss == null || discuss.getDid() <= 0) {
            return ResponseEntity.error("改讨论话题不存在！");
        }

        // 增加阅读量
        threadPool.execute(() -> {
            // 1、更新数据库
            discussService.update(
                    Wrappers.lambdaUpdate(Discuss.class)
                            .set(Discuss::getReadcount, discuss.getReadcount() + 1)
                            .set(Discuss::getUpdatetime, LocalDateTime.now())
                            .eq(Discuss::getDid, did)
            );
            // 2. 返回的对象阅读量 + 1
            discuss.setReadcount(discuss.getReadcount() + 1);
        });

        // 任务1: 查询 discuss 中的 username
        CompletableFuture<DiscussVO> task1 = CompletableFuture.supplyAsync(() -> {
            DiscussVO discussVO = new DiscussVO();
            BeanUtils.copyProperties(discuss, discussVO);
            User user = userService.getById(discuss.getUid());
            if (user != null && user.getNickname() != null) {
                discussVO.setNickName(user.getNickname());
            }
            return discussVO;
        }, threadPool);

        // 任务2: 查询 discuss 中的 comment 列表
        CompletableFuture<List<CommentVO>> task2 = CompletableFuture.supplyAsync(
                () -> commentService.getCommentList(did), threadPool);
        CompletableFuture<Void> allOf = CompletableFuture.allOf(task1, task2);

        HashMap<String, Object> result = new HashMap<>();
        result.put("discuss", task1.get());
        result.put("commentList", task2.get());

        return ResponseEntity.success(result);
    }

    /**
     * 话题讨论点赞
     */
    @RequestMapping("/support")
    public ResponseEntity support(Long did) {
        if (did == null || did <= 0) {
            return ResponseEntity.error("参数错误");
        }
        kafkaTemplate.send(AppVariable.DISCUSS_SUPPORT_TOPIC, did + "_" + SecurityUtils.getCurrentUser().getUid());
        return ResponseEntity.success(true);
    }

    /**
     * 监听 Kafka 中话题讨论点赞
     */
    @KafkaListener(topics = AppVariable.DISCUSS_SUPPORT_TOPIC)
    public void listen(String data, Acknowledgment acknowledgment) {
        String[] split = data.split("_");
        Long did = Long.valueOf(split[0]);
        Long uid = Long.valueOf(split[1]);

        // 0. 判断当前用户是否已经点赞过当前话题
        DiscussSupport one = discussSupportService.getOne(
                Wrappers.lambdaQuery(DiscussSupport.class)
                        .eq(DiscussSupport::getDid, did)
                        .eq(DiscussSupport::getUid, uid)
        );

        if (one == null) {

            // 1. 修改讨论表中的点赞数
            Discuss discuss = discussService.getById(did);
            discuss.setSupportcount(discuss.getSupportcount() + 1);
            boolean updateResult = discussService.updateById(discuss);
            if (!updateResult) {
                return;
            }
            // 2. 在点赞详情表中添加记录
            DiscussSupport discussSupport = new DiscussSupport();
            discussSupport.setDid(did);
            discussSupport.setUid(uid);

            discussSupportService.save(discussSupport);
        }
        // 3. 手动确认消息
        acknowledgment.acknowledge();
    }
}
